/*******************************************************************************
New Unit Technologies, a division of DBI, LLC.

Created for CS450 at West Virginia University, Fall 2003

Developers:	Matthew Bradley
		Andrew Lowery
		Richard Paletta
		J. Ryan Sigler

File name: main.c
*******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include "pcb.h"
#include "mpx.h"
#include "mpx_supt.h"
#include "int_supt.h"
#include "IO_SUPT.H"

PCB *running;
queue *READY_QUEUE;
queue *SUS_READY_QUEUE;
queue *BLOCKED_QUEUE;
queue *SUS_BLOCKED_QUEUE;

extern context *context_p;

extern struct IOCB IOCB1[NUM_DEVICES];

extern char p_msg[80];
extern int p_length;

PCB *comproc;

void main(void)
{
    PCB *pcb_n;
    char name[10];
    int count;
        
	sprintf(p_msg, "Initializing MPX\n\0");         				//Initialize MPX
	p_length = strlen(p_msg);
	//sys_req(WRITE, TERMINAL, p_msg, &p_length);
	printf("Initializing MPX\n");
	
	sys_init(MODULE_F);
    
    sprintf(p_msg, "Initializing Process Queues\n\0");
	p_length = strlen(p_msg);
	//sys_req(WRITE, TERMINAL, p_msg, &p_length);
	printf("Initializing Process Queues\n");


	/* ALLOCATE  and INITIALIZE QUEUES */

	READY_QUEUE = (queue *) sys_alloc_mem((size_t) sizeof(queue));
	initialize(READY_QUEUE);
	
	READY_QUEUE->count = 0;

	SUS_READY_QUEUE = (queue *) sys_alloc_mem((size_t) sizeof(queue));
	initialize(SUS_READY_QUEUE);
	
	SUS_READY_QUEUE->count = 0;

	BLOCKED_QUEUE = (queue *) sys_alloc_mem((size_t) sizeof(queue));
	initialize(BLOCKED_QUEUE);
	
	BLOCKED_QUEUE->count = 0;

	SUS_BLOCKED_QUEUE = (queue *) sys_alloc_mem((size_t) sizeof(queue));
	initialize(SUS_BLOCKED_QUEUE);
	
	SUS_BLOCKED_QUEUE->count = 0;
	
	//Initialize IOCB strucures
	for(count = 0; count<NUM_DEVICES; count++){
        IOCB1[count].flag = 1;
        IOCB1[count].current = NULL;
        IOCB1[count].buffer = NULL;
        IOCB1[count].length = NULL;
        IOCB1[count].next = NULL;
    }
    
    trm_open(&(IOCB1[TERMINAL - 1].flag));
    com_open(&(IOCB1[COM_PORT - 1].flag));
    //prt_open(&(IOCB1[PRINTER - 1].flag));

	sprintf(p_msg, "Loading NUT Interface\n\0");
	p_length = strlen(p_msg);
	//sys_req(WRITE, TERMINAL, p_msg, &p_length);
	printf("Loading NUT Interface\n");

	//Create comhan process
	pcb_n = newPCB();
    sprintf(name, "comhan");
    setupPCB(pcb_n, name, SYS, 128, 5096, 1);
    context_p = (context*)(*pcb_n).top;
	context_p->DS = _DS;
	context_p->ES = _ES;
	context_p->CS = FP_SEG(&comhan);
	context_p->IP = FP_OFF(&comhan);
	context_p->FLAGS = 0x200;
    pinsert(pcb_n, READY_QUEUE);
    comproc = pcb_n;
    
    //Create Idle process
    loadprocs("IDLE","-128");
    pcb_n = findpcb("IDLE");
    removepcb(pcb_n, SUS_READY_QUEUE);
    pinsert(pcb_n, READY_QUEUE);
    (*pcb_n).pclass=SYS;
    
    sys_set_vec(sys_call);
    printf("Calling Dispatch\n");
    dispatch();    
    
    //comhan();                        				 //Load comhan

	sprintf(p_msg, "Cleaning up system. Exiting MPX\n\0");
	p_length = strlen(p_msg);
	sys_req(WRITE, TERMINAL, p_msg, &p_length);

	sys_exit();                           				 //Exit MPX
}
